#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <algorithm>

using namespace std;

class Dish {
public:
    string dishId;
    string dishName;
    double price;
    string merchantName;

    void displayInfo() {
        cout << "Dish ID: " << dishId << ", Dish Name: " << dishName << ", Price: " << price << ", Merchant: " << merchantName << endl;
    }
};

class Merchant {
public:
    string merchantName;
    string location;
    string phoneNumber;

    void displayInfo() {
        cout << "Merchant Name: " << merchantName << ", Location: " << location << ", Phone Number: " << phoneNumber << endl;
    }
};

class Student {
public:
    string accountId;
    string nickname;
    string phoneNumber;

    void displayInfo() {
        cout << "Account ID: " << accountId << ", Nickname: " << nickname << ", Phone Number: " << phoneNumber << endl;
    }
};

class Comment {
public:
    string dishId;
    string accountId;
    int rating;
    string commentText;
    string commentTime;

    void displayInfo() {
        cout << "Dish ID: " << dishId << ", Account ID: " << accountId << ", Rating: " << rating << ", Comment: " << commentText << ", Time: " << commentTime << endl;
    }
};

class CafeteriaSystem {
private:
    vector<Dish> dishes;
    vector<Merchant> merchants;
    vector<Student> students;
    vector<Comment> comments;

    void saveDataToFile(const string& filename) {
        ofstream file(filename);
        if (file.is_open()) {
            for (const auto& dish : dishes) {
                file << "Dish," << dish.dishId << "," << dish.dishName << "," << dish.price << "," << dish.merchantName << endl;
            }
            for (const auto& merchant : merchants) {
                file << "Merchant," << merchant.merchantName << "," << merchant.location << "," << merchant.phoneNumber << endl;
            }
            for (const auto& student : students) {
                file << "Student," << student.accountId << "," << student.nickname << "," << student.phoneNumber << endl;
            }
            for (const auto& comment : comments) {
                file << "Comment," << comment.dishId << "," << comment.accountId << "," << comment.rating << "," << comment.commentText << "," << comment.commentTime << endl;
            }
            file.close();
            cout << "Data saved to file." << endl;
        } else {
            cout << "Unable to open file for saving data." << endl;
        }
    }

    void loadDataFromFile(const string& filename) {
        ifstream file(filename);
        if (file.is_open()) {
            string line;
            while (getline(file, line)) {
                stringstream ss(line);
                string type;
                getline(ss, type, ',');
                if (type == "Dish") {
                    Dish dish;
                    getline(ss, dish.dishId, ',');
                    getline(ss, dish.dishName, ',');
                    string priceStr;
                    getline(ss, priceStr, ',');
                    dish.price = stod(priceStr);
                    getline(ss, dish.merchantName, ',');
                    dishes.push_back(dish);
                } else if (type == "Merchant") {
                    Merchant merchant;
                    getline(ss, merchant.merchantName, ',');
                    getline(ss, merchant.location, ',');
                    getline(ss, merchant.phoneNumber, ',');
                    merchants.push_back(merchant);
                } else if (type == "Student") {
                    Student student;
                    getline(ss, student.accountId, ',');
                    getline(ss, student.nickname, ',');
                    getline(ss, student.phoneNumber, ',');
                    students.push_back(student);
                } else if (type == "Comment") {
                    Comment comment;
                    getline(ss, comment.dishId, ',');
                    getline(ss, comment.accountId, ',');
                    string ratingStr;
                    getline(ss, ratingStr, ',');
                    comment.rating = stoi(ratingStr);
                    getline(ss, comment.commentText, ',');
                    getline(ss, comment.commentTime, ',');
                    comments.push_back(comment);
                }
            }
            file.close();
            cout << "Data loaded from file." << endl;
        } else {
            cout << "Unable to open file for loading data." << endl;
        }
    }

public:
    void addDish(const string& dishId, const string& dishName, double price, const string& merchantName) {
        Dish newDish = {dishId, dishName, price, merchantName};
        dishes.push_back(newDish);
        cout << "Dish added successfully." << endl;
    }

    void displayAllDishes() {
        cout << "All Dishes:" << endl;
        for (const auto& dish : dishes) {
            dish.displayInfo();
        }
    }

    void removeDish(const string& dishId) {
        auto it = std::remove_if(dishes.begin(), dishes.end(), [&](const Dish& dish) { return dish.dishId == dishId; });
        if (it != dishes.end()) {
            dishes.erase(it, dishes.end());
            cout << "Dish removed successfully." << endl;
        } else {
            cout << "Dish not found." << endl;
        }
    }

    void addMerchant(const string& merchantName, const string& location, const string& phoneNumber) {
        Merchant newMerchant = {merchantName, location, phoneNumber};
        merchants.push_back(newMerchant);
        cout << "Merchant added successfully." << endl;
    }

    void displayAllMerchants() {
        cout << "All Merchants:" << endl;
        for (const auto& merchant : merchants) {
            merchant.displayInfo();
        }
    }

    void removeMerchant(const string& merchantName) {
        auto it = std::remove_if(merchants.begin(), merchants.end(), [&](const Merchant& merchant) { return merchant.merchantName == merchantName; });
        if (it != merchants.end()) {
            merchants.erase(it, merchants.end());
            cout << "Merchant removed successfully." << endl;
        } else {
            cout << "Merchant not found." << endl;
        }
    }

    void addStudent(const string& accountId, const string& nickname, const string& phoneNumber) {
        Student newStudent = {accountId, nickname, phoneNumber};
        students.push_back(newStudent);
        cout << "Student added successfully." << endl;
    }

    void displayAllStudents() {
        cout << "All Students:" << endl;
        for (const auto& student : students) {
            student.displayInfo();
        }
    }

    void removeStudent(const string& accountId) {
        auto it = std::remove_if(students.begin(), students.end(), [&](const Student& student) { return student.accountId == accountId; });
        if (it != students.end()) {
            students.erase(it, students.end());
            cout << "Student removed successfully." << endl;
        } else {
            cout << "Student not found." << endl;
        }
    }

    void addComment(const string& dishId, const string& accountId, int rating, const string& commentText, const string& commentTime) {
        Comment newComment = {dishId, accountId, rating, commentText, commentTime};
        comments.push_back(newComment);
        cout << "Comment added successfully." << endl;
    }

    void displayAllComments() {
        cout << "All Comments:" << endl;
        for (const auto& comment : comments) {
            comment.displayInfo();
        }
    }

    void sortDishesByRating() {
        sort(comments.begin(), comments.end(), [](const Comment& c1, const Comment& c2) {
            return c1.rating > c2.rating;
        });
        cout << "Dishes sorted by rating." << endl;
    }

    void runSystem() {
        // Load data from file
        loadDataFromFile("data.txt");

        // Sample operations
        addDish("001", "Spaghetti", 8.5, "Cafeteria A");
        addDish("002", "Salad", 6.0, "Cafeteria B");
        displayAllDishes();

        addMerchant("Cafeteria A", "Central Square", "1234567890");
        addMerchant("Cafeteria B", "East Wing", "9876543210");
        displayAllMerchants();

        addStudent("S001", "Alice", "1111111111");
        addStudent("S002", "Bob", "2222222222");
        displayAllStudents();

        addComment("001", "S001", 4, "Tasty!", "2022-01-15");
        addComment("001", "S002", 3, "Good portion size.", "2022-01-16");
        displayAllComments();

        sortDishesByRating();

        // Save data to file
        saveDataToFile("data.txt");
    }
};

int main() {
    CafeteriaSystem system;
    system.runSystem();

    return 0;
}
